package com.config;

import java.io.IOException;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.env.Environment;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
import org.springframework.stereotype.Component;

/**
 * 
 * @author 北京八维博大科技 薛建新
 * @date 2022年11月16日 10:17:15
 * @Copyright 北京八维博大科技
 */
//@Component
public class TestBeanDefinitionRegistryPostProcessor
		implements BeanDefinitionRegistryPostProcessor, PriorityOrdered, EnvironmentAware {
	private Environment environment;

	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		System.out.println(
				"1111##################################[BeanDefinitionRegistryPostProcessor] postProcessBeanDefinitionRegistry");

		// ClassPathBeanDefinitionScanner scanner = new
		// ClassPathBeanDefinitionScanner(registry, false);
		// TypeFilter helloServiceFilter = new AssignableTypeFilter(HelloService.class);
		// scanner.addIncludeFilter(helloServiceFilter);
		// scanner.scan(basePackages);

		// 在生成jar包的时候生成需要注册的bean 列表
		SimpleMetadataReaderFactory readerFactory = new SimpleMetadataReaderFactory();
		// org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.scanCandidateComponents(String)
//		ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition();
		// 使用工厂构建一个metadataReader读取器
		try {
			MetadataReader metadataReader = readerFactory.getMetadataReader("com.xue.test.Hello");
			System.out.println("metadataReader=null?" + (metadataReader == null));

			boolean hasAnno = metadataReader.getAnnotationMetadata()
					.hasAnnotation("org.springframework.stereotype.Service");
			System.out.println("hasAnno?" + (hasAnno));
			if (hasAnno) {

				boolean hasBean = registry.containsBeanDefinition("hello");
				System.out.println("bd=================================>" + hasBean);
				if (!hasBean) {
					BeanDefinition bd = new GenericBeanDefinition();
					bd.setBeanClassName("com.xue.test.Hello");
					registry.registerBeanDefinition("hello", bd);
				}
			}

		} catch (IOException e) {
			e.printStackTrace();
		}

		// 新增,把jar包解密后的类都手动注册到这里
//	        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(C.class);
//			BeanDefinition bd = new GenericBeanDefinition();
//			bd.setBeanClassName("com.xue.test.Hello");
//			registry.registerBeanDefinition("hello",bd);

//			// 查询和修改
//			BeanDefinition student = registry.getBeanDefinition("student");
//			// 删除
//			registry.removeBeanDefinition("student");
// new InputStreamResource(new FileInputStream(new File("a.txt"))
//			ClassPathBeanDefinitionScanner cpds= new ClassPathBeanDefinitionScanner(registry,true,this.environment,new ResourceLoader() {
//
//				@Override
//				public Resource getResource(String location) {
//					System.out.println(location);
//					return null;
//				}
//
//				@Override
//				public ClassLoader getClassLoader() {
//					return null;
//				}
//				
//			});
//			cpds.scan("com");

	}

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		// BeanFactoryPostProcessor
		// 调用时机在spring在读取beanDefinition信息之后，实例化bean之前。在这个时机，用户可以通过实现这个扩展接口来自行处理一些东西，比如修改已经注册的beanDefinition的元信息
		System.out.println(
				"222##################################[BeanDefinitionRegistryPostProcessor] postProcessBeanFactory");
	}

	@Override
	public int getOrder() {
		return 1;
	}

	@Override
	public void setEnvironment(Environment environment) {
		System.out.println("333##################################[Environment");
		this.environment = environment;
	}

}
